/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GoDutch;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * @author Molten Ice
 */
public class GoDutch extends MIDlet implements CommandListener {

    /**
     * This is the amount of decimal places for the current currency being used.
     * This should be modified if currency changes.
     * This should be used to know how many decimal places we are dealing with.
     */
    private int currencyDecimalValue = 3;
    private boolean midletPaused = false;
    //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">//GEN-BEGIN:|fields|0|
    private Command exitCommand;
    private Command exitCommand1;
    private Command calculateCommand;
    private Command aboutCommand;
    private Form EqualSplit;
    private TextField totalPriceTextField;
    private TextField numberOfPeopleTextField;
    private ChoiceGroup tipTypeChoiceGroup;
    private StringItem finalCostStringItem;
    private TextField tipTextField;
    private Spacer spacer;
    private StringItem unitCostStringItem;
    private Form ManualSplit;
    private Alert alert;
    //</editor-fold>//GEN-END:|fields|0|

    /**
     * The GoDutch constructor.
     */
    public GoDutch() {
    }

    //<editor-fold defaultstate="collapsed" desc=" Generated Methods ">//GEN-BEGIN:|methods|0|
    //</editor-fold>//GEN-END:|methods|0|
    //<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">//GEN-BEGIN:|0-initialize|0|0-preInitialize
    /**
     * Initilizes the application.
     * It is called only once when the MIDlet is started. The method is called before the <code>startMIDlet</code> method.
     */
    private void initialize() {//GEN-END:|0-initialize|0|0-preInitialize
        // write pre-initialize user code here
//GEN-LINE:|0-initialize|1|0-postInitialize
        // write post-initialize user code here
    }//GEN-BEGIN:|0-initialize|2|
    //</editor-fold>//GEN-END:|0-initialize|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: startMIDlet ">//GEN-BEGIN:|3-startMIDlet|0|3-preAction
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Started point.
     */
    public void startMIDlet() {//GEN-END:|3-startMIDlet|0|3-preAction
        // write pre-action user code here
        switchDisplayable(null, getEqualSplit());//GEN-LINE:|3-startMIDlet|1|3-postAction
        // write post-action user code here
    }//GEN-BEGIN:|3-startMIDlet|2|
    //</editor-fold>//GEN-END:|3-startMIDlet|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: resumeMIDlet ">//GEN-BEGIN:|4-resumeMIDlet|0|4-preAction
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Resumed point.
     */
    public void resumeMIDlet() {//GEN-END:|4-resumeMIDlet|0|4-preAction
        // write pre-action user code here
//GEN-LINE:|4-resumeMIDlet|1|4-postAction
        // write post-action user code here
    }//GEN-BEGIN:|4-resumeMIDlet|2|
    //</editor-fold>//GEN-END:|4-resumeMIDlet|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: switchDisplayable ">//GEN-BEGIN:|5-switchDisplayable|0|5-preSwitch
    /**
     * Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.
     * @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately
     * @param nextDisplayable the Displayable to be set
     */
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {//GEN-END:|5-switchDisplayable|0|5-preSwitch
        // write pre-switch user code here
        Display display = getDisplay();//GEN-BEGIN:|5-switchDisplayable|1|5-postSwitch
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }//GEN-END:|5-switchDisplayable|1|5-postSwitch
        // write post-switch user code here
    }//GEN-BEGIN:|5-switchDisplayable|2|
    //</editor-fold>//GEN-END:|5-switchDisplayable|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: commandAction for Displayables ">//GEN-BEGIN:|7-commandAction|0|7-preCommandAction
    /**
     * Called by a system to indicated that a command has been invoked on a particular displayable.
     * @param command the Command that was invoked
     * @param displayable the Displayable where the command was invoked
     */
    public void commandAction(Command command, Displayable displayable) {//GEN-END:|7-commandAction|0|7-preCommandAction
        // write pre-action user code here
        if (displayable == EqualSplit) {//GEN-BEGIN:|7-commandAction|1|49-preAction
            if (command == aboutCommand) {//GEN-END:|7-commandAction|1|49-preAction
                // write pre-action user code here
                about();
//GEN-LINE:|7-commandAction|2|49-postAction
                // write post-action user code here
            } else if (command == calculateCommand) {//GEN-LINE:|7-commandAction|3|41-preAction
                // write pre-action user code here
                calculate();
//GEN-LINE:|7-commandAction|4|41-postAction
                // write post-action user code here
            } else if (command == exitCommand) {//GEN-LINE:|7-commandAction|5|19-preAction
                // write pre-action user code here
                exitMIDlet();//GEN-LINE:|7-commandAction|6|19-postAction
                // write post-action user code here
            }//GEN-BEGIN:|7-commandAction|7|25-preAction
        } else if (displayable == ManualSplit) {
            if (command == exitCommand1) {//GEN-END:|7-commandAction|7|25-preAction
                // write pre-action user code here
                exitMIDlet();//GEN-LINE:|7-commandAction|8|25-postAction
                // write post-action user code here
            }//GEN-BEGIN:|7-commandAction|9|7-postCommandAction
        }//GEN-END:|7-commandAction|9|7-postCommandAction
        // write post-action user code here
    }//GEN-BEGIN:|7-commandAction|10|
    //</editor-fold>//GEN-END:|7-commandAction|10|

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand ">//GEN-BEGIN:|18-getter|0|18-preInit
    /**
     * Returns an initiliazed instance of exitCommand component.
     * @return the initialized component instance
     */
    public Command getExitCommand() {
        if (exitCommand == null) {//GEN-END:|18-getter|0|18-preInit
            // write pre-init user code here
            exitCommand = new Command("Exit", Command.EXIT, 0);//GEN-LINE:|18-getter|1|18-postInit
            // write post-init user code here
        }//GEN-BEGIN:|18-getter|2|
        return exitCommand;
    }
    //</editor-fold>//GEN-END:|18-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: EqualSplit ">//GEN-BEGIN:|14-getter|0|14-preInit
    /**
     * Returns an initiliazed instance of EqualSplit component.
     * @return the initialized component instance
     */
    public Form getEqualSplit() {
        if (EqualSplit == null) {//GEN-END:|14-getter|0|14-preInit
            // write pre-init user code here
            EqualSplit = new Form("Go Dutch", new Item[] { getTotalPriceTextField(), getNumberOfPeopleTextField(), getTipTypeChoiceGroup(), getTipTextField(), getSpacer(), getFinalCostStringItem(), getUnitCostStringItem() });//GEN-BEGIN:|14-getter|1|14-postInit
            EqualSplit.addCommand(getExitCommand());
            EqualSplit.addCommand(getCalculateCommand());
            EqualSplit.addCommand(getAboutCommand());
            EqualSplit.setCommandListener(this);//GEN-END:|14-getter|1|14-postInit
            // write post-init user code here
        }//GEN-BEGIN:|14-getter|2|
        return EqualSplit;
    }
    //</editor-fold>//GEN-END:|14-getter|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand1 ">//GEN-BEGIN:|24-getter|0|24-preInit
    /**
     * Returns an initiliazed instance of exitCommand1 component.
     * @return the initialized component instance
     */
    public Command getExitCommand1() {
        if (exitCommand1 == null) {//GEN-END:|24-getter|0|24-preInit
            // write pre-init user code here
            exitCommand1 = new Command("Exit", Command.EXIT, 0);//GEN-LINE:|24-getter|1|24-postInit
            // write post-init user code here
        }//GEN-BEGIN:|24-getter|2|
        return exitCommand1;
    }
    //</editor-fold>//GEN-END:|24-getter|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: ManualSplit ">//GEN-BEGIN:|22-getter|0|22-preInit
    /**
     * Returns an initiliazed instance of ManualSplit component.
     * @return the initialized component instance
     */
    public Form getManualSplit() {
        if (ManualSplit == null) {//GEN-END:|22-getter|0|22-preInit
            // write pre-init user code here
            ManualSplit = new Form("Manual Fit");//GEN-BEGIN:|22-getter|1|22-postInit
            ManualSplit.addCommand(getExitCommand1());
            ManualSplit.setCommandListener(this);//GEN-END:|22-getter|1|22-postInit
            // write post-init user code here
        }//GEN-BEGIN:|22-getter|2|
        return ManualSplit;
    }
    //</editor-fold>//GEN-END:|22-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: totalPriceTextField ">//GEN-BEGIN:|29-getter|0|29-preInit
    /**
     * Returns an initiliazed instance of totalPriceTextField component.
     * @return the initialized component instance
     */
    public TextField getTotalPriceTextField() {
        if (totalPriceTextField == null) {//GEN-END:|29-getter|0|29-preInit
            // write pre-init user code here
            totalPriceTextField = new TextField("Total Price", getDefaultPrice(), 32, TextField.DECIMAL);//GEN-LINE:|29-getter|1|29-postInit
            // write post-init user code here
        }//GEN-BEGIN:|29-getter|2|
        return totalPriceTextField;
    }
    //</editor-fold>//GEN-END:|29-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: numberOfPeopleTextField ">//GEN-BEGIN:|30-getter|0|30-preInit
    /**
     * Returns an initiliazed instance of numberOfPeopleTextField component.
     * @return the initialized component instance
     */
    public TextField getNumberOfPeopleTextField() {
        if (numberOfPeopleTextField == null) {//GEN-END:|30-getter|0|30-preInit
            // write pre-init user code here
            numberOfPeopleTextField = new TextField("Number of People", "1", 32, TextField.NUMERIC);//GEN-LINE:|30-getter|1|30-postInit
            // write post-init user code here
        }//GEN-BEGIN:|30-getter|2|
        return numberOfPeopleTextField;
    }
    //</editor-fold>//GEN-END:|30-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: tipTypeChoiceGroup ">//GEN-BEGIN:|33-getter|0|33-preInit
    /**
     * Returns an initiliazed instance of tipTypeChoiceGroup component.
     * @return the initialized component instance
     */
    public ChoiceGroup getTipTypeChoiceGroup() {
        if (tipTypeChoiceGroup == null) {//GEN-END:|33-getter|0|33-preInit
            // write pre-init user code here
            tipTypeChoiceGroup = new ChoiceGroup("Calculating Tips", Choice.EXCLUSIVE);//GEN-BEGIN:|33-getter|1|33-postInit
            tipTypeChoiceGroup.append("Percentages", null);
            tipTypeChoiceGroup.append("Constant Value", null);
            tipTypeChoiceGroup.setFitPolicy(Choice.TEXT_WRAP_DEFAULT);
            tipTypeChoiceGroup.setSelectedFlags(new boolean[] { true, false });//GEN-END:|33-getter|1|33-postInit
            // write post-init user code here
        }//GEN-BEGIN:|33-getter|2|
        return tipTypeChoiceGroup;
    }
    //</editor-fold>//GEN-END:|33-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: calculateCommand ">//GEN-BEGIN:|39-getter|0|39-preInit
    /**
     * Returns an initiliazed instance of calculateCommand component.
     * @return the initialized component instance
     */
    public Command getCalculateCommand() {
        if (calculateCommand == null) {//GEN-END:|39-getter|0|39-preInit
            // write pre-init user code here
            calculateCommand = new Command("Calculate", Command.OK, 0);//GEN-LINE:|39-getter|1|39-postInit
            // write post-init user code here
        }//GEN-BEGIN:|39-getter|2|
        return calculateCommand;
    }
    //</editor-fold>//GEN-END:|39-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: finalCostStringItem ">//GEN-BEGIN:|38-getter|0|38-preInit
    /**
     * Returns an initiliazed instance of finalCostStringItem component.
     * @return the initialized component instance
     */
    public StringItem getFinalCostStringItem() {
        if (finalCostStringItem == null) {//GEN-END:|38-getter|0|38-preInit
            // write pre-init user code here
            finalCostStringItem = new StringItem("Final Cost", null);//GEN-LINE:|38-getter|1|38-postInit
            // write post-init user code here
        }//GEN-BEGIN:|38-getter|2|
        return finalCostStringItem;
    }
    //</editor-fold>//GEN-END:|38-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: tipTextField ">//GEN-BEGIN:|43-getter|0|43-preInit
    /**
     * Returns an initiliazed instance of tipTextField component.
     * @return the initialized component instance
     */
    public TextField getTipTextField() {
        if (tipTextField == null) {//GEN-END:|43-getter|0|43-preInit
            // write pre-init user code here
            tipTextField = new TextField("Tip", "0", 32, TextField.DECIMAL);//GEN-LINE:|43-getter|1|43-postInit
            // write post-init user code here
        }//GEN-BEGIN:|43-getter|2|
        return tipTextField;
    }
    //</editor-fold>//GEN-END:|43-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: unitCostStringItem ">//GEN-BEGIN:|45-getter|0|45-preInit
    /**
     * Returns an initiliazed instance of unitCostStringItem component.
     * @return the initialized component instance
     */
    public StringItem getUnitCostStringItem() {
        if (unitCostStringItem == null) {//GEN-END:|45-getter|0|45-preInit
            // write pre-init user code here
            unitCostStringItem = new StringItem("Each Person Pays (Including Tip)", null);//GEN-LINE:|45-getter|1|45-postInit
            // write post-init user code here
        }//GEN-BEGIN:|45-getter|2|
        return unitCostStringItem;
    }
    //</editor-fold>//GEN-END:|45-getter|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: spacer ">//GEN-BEGIN:|46-getter|0|46-preInit
    /**
     * Returns an initiliazed instance of spacer component.
     * @return the initialized component instance
     */
    public Spacer getSpacer() {
        if (spacer == null) {//GEN-END:|46-getter|0|46-preInit
            // write pre-init user code here
            spacer = new Spacer(16, 30);//GEN-BEGIN:|46-getter|1|46-postInit
            spacer.setPreferredSize(-1, 20);//GEN-END:|46-getter|1|46-postInit
            // write post-init user code here
        }//GEN-BEGIN:|46-getter|2|
        return spacer;
    }
    //</editor-fold>//GEN-END:|46-getter|2|

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: alert ">//GEN-BEGIN:|47-getter|0|47-preInit
    /**
     * Returns an initiliazed instance of alert component.
     * @return the initialized component instance
     */
    public Alert getAlert() {
        if (alert == null) {//GEN-END:|47-getter|0|47-preInit
            // write pre-init user code here
            alert = new Alert("Error", "An Unknown Error Occured", null, AlertType.ERROR);//GEN-BEGIN:|47-getter|1|47-postInit
            alert.setTimeout(2000);//GEN-END:|47-getter|1|47-postInit
            // write post-init user code here
        }//GEN-BEGIN:|47-getter|2|
        return alert;
    }
    //</editor-fold>//GEN-END:|47-getter|2|
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: aboutCommand ">//GEN-BEGIN:|48-getter|0|48-preInit
    /**
     * Returns an initiliazed instance of aboutCommand component.
     * @return the initialized component instance
     */
    public Command getAboutCommand() {
        if (aboutCommand == null) {//GEN-END:|48-getter|0|48-preInit
            // write pre-init user code here
            aboutCommand = new Command("About", Command.HELP, 0);//GEN-LINE:|48-getter|1|48-postInit
            // write post-init user code here
        }//GEN-BEGIN:|48-getter|2|
        return aboutCommand;
    }
    //</editor-fold>//GEN-END:|48-getter|2|

    /**
     * Returns a display instance.
     * @return the display instance.
     */
    public Display getDisplay() {
        return Display.getDisplay(this);
    }

    /**
     * Exits MIDlet.
     */
    public void exitMIDlet() {
        switchDisplayable(null, null);
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */
    public void startApp() {
        if (midletPaused) {
            resumeMIDlet();
        } else {
            initialize();
            startMIDlet();
        }
        midletPaused = false;
    }

    /**
     * Called when MIDlet is paused.
     */
    public void pauseApp() {
        midletPaused = true;
    }

    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */
    public void destroyApp(boolean unconditional) {
    }

    private void calculate() {


        new Thread(new Runnable() {

            public void run() {
                //Initialize the answer values
                float finalCost = 0;
                float individualCost = 0;
                try {
                    //First get the values from the user's input
                    float totalValue = Float.parseFloat(totalPriceTextField.getString());
                    int numberOfPeople = Integer.parseInt(numberOfPeopleTextField.getString());

                    //Tip can be in either constant value or percentage, will be decided with 'choiceGroup'
                    //0 for percentage, 1 for constant
                    int tipType = tipTypeChoiceGroup.getSelectedIndex();
                    float tipAmount = Float.parseFloat(tipTextField.getString());

                    //Change the tipAmount to a percentage if it is the case
                    //Remember that even though the final percentage might have precision errors this is good as the point of this app is to approximate the amount each person has to pay, no one has 1 baiza to pay
                    if (tipType == 0 /* tip type is a percentage value */) {
                        tipAmount = totalValue * (tipAmount / 100);
                    }

                    //Run some primitive checks on what was inputted
                    //By now if text was inputted or nothing was inputted it SHOULD have been caught
                    //So thats why it is safe to run the following checks
                    if ((totalValue < 0) || (numberOfPeople < 1) || (tipAmount < 0)) {
                        throw new NumberFormatException();
                    }

                    //Do the calculations now
                    finalCost = round(totalValue + tipAmount, currencyDecimalValue);
                    individualCost = round(finalCost / numberOfPeople, currencyDecimalValue);

                    //Set the final values in the form
                    finalCostStringItem.setText(String.valueOf(finalCost));
                    unitCostStringItem.setText(String.valueOf(individualCost));
                } catch (NumberFormatException e) {
                    alert = new Alert("Incorrect Value(s) Entered", "Please re-check the numbers you inputted.", null, AlertType.ERROR);
                    alert.setTimeout(2000);
                    getDisplay().setCurrent(alert);
                }
            }
        }).start();

    }

    private static float round(float number, int decimalPlaces) {
        //First create a decimal value that would be in terms of 10s eg 2 = 1000, 3 = 10000 etc
        //The point of this is to transpose the wanted float values all to the left side of the
        //decimal point
        int tempDecimalPlaces = 1;
        for (int x = 0; x < decimalPlaces; x++) {
            tempDecimalPlaces *= 10;
        }
        decimalPlaces = tempDecimalPlaces;

        //Now that that is done time to round the value
        //First, lets get the decimal value in int form
        float testWhetherToRoundUp = (number * decimalPlaces);
        int decimalInIntForm = (int) testWhetherToRoundUp;

        //Now to test whether to round up or not!
        if (((testWhetherToRoundUp - decimalInIntForm) * 10) >= 5) {
            //Round up
            decimalInIntForm++;
        } else {
            //Round Down i.e. do nothing as no need to round up the value!
        }

        //get the answer back in float
        number = ((float) decimalInIntForm / decimalPlaces);

        return number;
    }

    /**
     * Gets the default price based on the local field currencyDecimalValue
     * @return
     */
    private String getDefaultPrice() {
        String finalDecimalValue = "0.";
        for (int x = 0; x < currencyDecimalValue; x++) {
            finalDecimalValue = finalDecimalValue + "0";
        }
        return finalDecimalValue;
    }

    private void about() {
        //The about message
        String aboutMessage = "Go Dutch v" + getAppProperty("MIDlet-Version")
                + "\n"
                + "\n"
                + "Developed by Karan Shah"
                + "\n"
                + "http://www.netsafehouse.com/";

        //The about alert is shown
        alert = new Alert("About", aboutMessage, null, AlertType.INFO);
        alert.setTimeout(Alert.FOREVER);
        getDisplay().setCurrent(alert);
    }
}
